home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Sample Code / Networking / OTSimpleDownloadHTTP1.0d1 / OTSimpleDownloadHTTPTest.c < prev    next >
Encoding:
Text File  |  1997-09-02  |  6.1 KB  |  243 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        OTSimpleDownloadHTTPTest.c
  3.  
  4.     Contains:    A test program for the simple HTTP download sample.
  5.  
  6.     Written by:    Quinn "The Eskimo!"
  7.  
  8.     Copyright:    © 1997 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.     You may incorporate this sample code into your applications without
  13.     restriction, though the sample code has been provided "AS IS" and the
  14.     responsibility for its operation is 100% yours.  However, what you are
  15.     not permitted to do is to redistribute the source as "DSC Sample Code"
  16.     after having made changes. If you're going to re-distribute the source,
  17.     we require that you make it clear in the source that the code was
  18.     descended from Apple Sample Code, but that you've made changes.
  19. */
  20.  
  21. /////////////////////////////////////////////////////////////////////
  22. // The OT debugging macros in <OTDebug.h> require this variable to
  23. // be set.
  24.  
  25. #ifndef qDebug
  26. #define qDebug    1
  27. #endif
  28.  
  29. /////////////////////////////////////////////////////////////////////
  30. // Pick up all the standard OT stuff.
  31.  
  32. #include <OpenTransport.h>
  33.  
  34. /////////////////////////////////////////////////////////////////////
  35. // Pick up all the OT TCP/IP stuff.
  36.  
  37. #include <OpenTptInternet.h>
  38.  
  39. /////////////////////////////////////////////////////////////////////
  40. // Pick up the OTDebugBreak and OTAssert macros.
  41.  
  42. #include <OTDebug.h>
  43.  
  44. /////////////////////////////////////////////////////////////////////
  45. // OTDebugStr is not defined in any OT header files, but it is
  46. // exported by the libraries, so we define the prototype here.
  47.  
  48. extern pascal void OTDebugStr(const char* str);
  49.  
  50. #include <OpenTptInternet.h>
  51. #include <PLStringFuncs.h>
  52. #include <Threads.h>
  53. #include <Files.h>
  54.  
  55. #include <string.h>
  56. #include <stdio.h>
  57. #include <ctype.h>
  58.  
  59. #include "OTSimpleDownloadHTTP.h"
  60.  
  61. enum {
  62.     kNotHTTPURLErr = -666,
  63.     kWhatImplementationErr = -667
  64. };
  65.  
  66. enum {
  67.     kDownloadSimple,
  68.     kDownloadFaster
  69. };
  70.  
  71. static OSStatus DownloadURL(const char *urlString)
  72. {
  73.     OSStatus err;
  74.     size_t hostCharCount;
  75.     char hostName[256];
  76.     Str255 tickCountString;
  77.     Str255 destFileName;
  78.     FSSpec destFSSpec;
  79.     short destFileRefNum;
  80.     char httpGetCommand[256];
  81.     OTTimeStamp startTime;
  82.     UInt32 timeToDownload;
  83.     long fileSize;
  84.     
  85.     err = noErr;
  86.     // First check that the urlString begins with "http://"
  87.     if ( strspn(urlString, "http://") != strlen("http://") ) {
  88.         err = kNotHTTPURLErr;
  89.     }
  90.  
  91.     // Now skip over the "http://" and extract the host name.
  92.     if (err == noErr) {
  93.         // Skip over the "http://".
  94.         urlString += strlen("http://");
  95.         
  96.         // Count the characters before the next slash.
  97.         hostCharCount = strcspn(urlString, "/");
  98.         
  99.         // Extract those characters from the URL into hostName
  100.         //  and then make sure it's null terminated.
  101.         (void) strncpy(hostName, urlString, hostCharCount);
  102.         hostName[hostCharCount] = 0;
  103.         urlString += hostCharCount;
  104.         
  105.         // Add a ":80" to the host name if necessary.
  106.         if ( strchr( hostName, ':' ) == nil ) {
  107.             strcat( hostName, ":80" );
  108.         }
  109.  
  110.         if (err == noErr) {
  111.             NumToString(TickCount(), tickCountString);
  112.             PLstrcpy(destFileName, "\pSimpleDownload#");
  113.             PLstrcat(destFileName, tickCountString);
  114.             (void) FSMakeFSSpec(0, 0, destFileName, &destFSSpec);
  115.             (void) FSpCreate(&destFSSpec, 'R*ch', 'TEXT', 0);
  116.             err = FSpOpenDF(&destFSSpec, fsRdWrPerm, &destFileRefNum);
  117.             if (err != noErr) {
  118.                 destFileRefNum = 0;
  119.             }
  120.         }
  121.         
  122.         if (err == noErr) {
  123.             // Now place the URL into the HTTP command that we send to DownloadHTTPSimple.
  124.             if ( *urlString == 0 ) {
  125.                 urlString = "/";
  126.             }
  127.             (void) sprintf(httpGetCommand, "GET %s HTTP/1.0%c%c%c%c", urlString, 13, 10, 13, 10);
  128.             printf("Calling DownloadHTTPXxxx(“%s”, “%s”, %04x).\n", hostName, urlString, destFileRefNum);
  129.             
  130.             OTGetTimeStamp(&startTime);
  131.             err = DownloadHTTPSimple(hostName, httpGetCommand, destFileRefNum);
  132.             timeToDownload = OTElapsedMicroseconds(&startTime);
  133.         }
  134.  
  135.         if (err == noErr) {
  136.             OTAssert( "DownloadURL: GetFPos failed", GetFPos(destFileRefNum, &fileSize) == noErr);
  137.             printf("Bytes downloaded: %d.\n", fileSize);
  138.             printf("Time to download: %dus.\n", timeToDownload);
  139.             printf("Bytes per second: %f.\n", (float) fileSize / (((float) timeToDownload) / 1000000.0) );
  140.         }
  141.  
  142.         // Clean up.
  143.         if (destFileRefNum != 0) {
  144.             (void) FSClose(destFileRefNum);
  145.         }
  146.         if (err != noErr) {
  147.             //(void) FSpDelete(&destFSSpec);
  148.         }
  149.  
  150.     }
  151.  
  152.     return (err);
  153. }
  154.  
  155. static UInt32 gLastPrinted = 0;
  156.  
  157. static pascal OSStatus ProgressThread(void *junkParam)
  158. {
  159.     #pragma unused(junkParam)
  160.     OSStatus junk;
  161.  
  162.     while (true) {
  163.         if ( TickCount() > (gLastPrinted + 60) ) {
  164.             printf(".");
  165.             fflush(stdout);
  166.             gLastPrinted = TickCount();
  167.         }
  168.         junk = YieldToAnyThread();
  169.         OTAssert("ProgressThread: YieldToAnyThread failed", junk == noErr);
  170.     }
  171.  
  172.     return (noErr);    
  173. }
  174.  
  175. static const char *defaultURLs[10] = {
  176. "http://www.apple.com",
  177. "http://www.adr.apple.com",
  178. "http://devworld.apple.com/dev/opentransport/Download/OT1.1.1.sea.hqx",
  179. "http://devworld.apple.com/dev/technotes.shtml",
  180. "",
  181. "",
  182. "",
  183. "",
  184. "",
  185. ""
  186. };
  187.  
  188. void main(void)
  189. {
  190.     OSStatus err;
  191.     OSStatus junk;
  192.     char urlString[256];
  193.     UInt32 i;
  194.     ThreadID progressThread;
  195.     
  196.     printf("Hello Cruel World!\n");
  197.     printf("\n");
  198.     printf("OTDownloadHTTP!\n");
  199.     printf("-- Downloads a URL using OT's thread support\n");
  200.     printf("-- or using notifiers.\n");
  201.     printf("\n");
  202.  
  203.     err = InitOpenTransport();
  204.     if (err == noErr) {
  205.         
  206.         for (i = 0; i < 10; i++) {
  207.             if ( *defaultURLs[i] != 0 ) {
  208.                 printf("%d> %s\n", i, defaultURLs[i]);
  209.             }
  210.         }
  211.         printf("\n");
  212.         printf("Enter a URL (or type a number from the above list):\n");
  213.         gets(urlString);
  214.         if ( strlen(urlString) == 1 && isdigit(urlString[0])) {
  215.             strcpy( urlString, defaultURLs[ urlString[0] - '0' ] );
  216.         }
  217.         if ( urlString[0] == 0 ) {
  218.             strcpy( urlString, defaultURLs[0] );
  219.         }
  220.         err = NewThread(kCooperativeThread,
  221.                             (ThreadEntryProcPtr) ProgressThread, nil,
  222.                             0, kCreateIfNeeded,
  223.                             nil,
  224.                             &progressThread);
  225.         if (err == noErr) {
  226.             err = DownloadURL(urlString);
  227.             junk = DisposeThread(progressThread, nil, true);
  228.             OTAssert("main: DisposeThread failed", junk == noErr);
  229.         }
  230.         
  231.         CloseOpenTransport();
  232.     }
  233.     
  234.     if (err == noErr) {
  235.         printf("Success.\n");
  236.     } else {
  237.         printf("Failed with error %d.\n", err);
  238.     }    
  239.     printf("Done.  Press command-Q to Quit.\n");
  240. }
  241.  
  242.  
  243.